#include "log.h"

void bench(const std::string &logger_name, size_t td_count, size_t msg_count, size_t msg_len)
{
    // 1、获取日志器
    Log::Logger::ptr logger = Log::gttLogger(logger_name);
    if (logger.get() == nullptr)
        return;
    std::cout << "测试日志: " << msg_count << "条, 总大小: " << (msg_count * msg_len) / 1024 << "KB" << std::endl;
    // 2、组织指定长度的日志消息
    std::string msg(msg_len - 1, 'Y');
    // 3、创建指定数量线程
    std::vector<std::thread> threads;
    std::vector<double> diff_arr(td_count);
    size_t msg_per_td = msg_count / td_count;
    for (int i = 0; i < td_count; ++i)
    {
        threads.emplace_back([&, i]()
                             {
            // 4、线程函数内部开始计时
            auto start = std::chrono::high_resolution_clock::now();
            // 5、循环写入日志
            for (int j = 0; j < msg_per_td; ++j)
            {
                logger->debug("%s", msg.c_str());
            }
            // 6、线程函数内部结束计时
            auto end = std::chrono::high_resolution_clock::now();
            std::chrono::duration<double> diff = end - start;
            diff_arr[i] = diff.count();
            std::cout << "线程" << ": " << i << ", 输出数量: " << msg_per_td << ", 耗时: " << diff.count() << "s" << std::endl; });
    }
    for (int i = 0; i < td_count; ++i)
        threads[i].join();
    // 7、计算总耗时
    double max_diff = diff_arr[0];
    for (int i = 1; i < td_count; ++i)
        max_diff = std::max(max_diff, diff_arr[i]);
    size_t msg_per_sec = msg_count / max_diff;
    size_t size_per_sec = (msg_count * msg_len) / (max_diff * 1024);
    // 8、输出打印
    std::cout << "总耗时: " << max_diff << "s" << std::endl;
    std::cout << "每秒输出日志数量: " << msg_per_sec << "条" << std::endl;
    std::cout << "每秒输出日志大小: " << size_per_sec << "KB" << std::endl;
}

void sync_bench()
{
    std::unique_ptr<Log::LoggerBuilder> builder(new Log::GlobalLoggerBuilder());
    builder->buildLoggerName("sync_logger");
    builder->buildFormatter();
    builder->buildLoggerType(Log::LoggerType::LOGGER_SYNC);
    builder->buildSink<Log::FileSink>("./logfile/sync.log");
    builder->build();
    bench("sync_logger", 3, 1000000, 100);
}

void async_bench()
{
    std::unique_ptr<Log::LoggerBuilder> builder(new Log::GlobalLoggerBuilder());
    builder->buildLoggerName("async_logger");
    builder->buildFormatter();
    builder->buildEnableUnsafeAsync();
    builder->buildLoggerType(Log::LoggerType::LOGGER_ASYNC);
    builder->buildSink<Log::FileSink>("./logfile/async.log");
    builder->build();
    bench("async_logger", 3, 1000000, 100);
}

int main()
{
    async_bench();

    return 0;
}